#!/usr/bin/env python
# --encoding=utf-8
# Copyright (c) 2015-2020, Zhejiang Uniview Technology Co., Ltd. All rights reserved.
# author: huxiaohua 03965

import sys
import time
import json
import datetime
import hashlib
import base64
import requests
import threading

global null
null = None

class HttpAccount(object):
    '''调取url'''
    def __init__(self,acc_server_ip,acc_port):
        self.acc_server_ip = acc_server_ip
        self.acc_port = acc_port

    def getResponse(self, openurl, url, headers, data):
        """
        获取响应体对象
        :param url:
        :param headers:
        :param data:
        :return:
        """
        try:
            # 适配post方法无消息体的情况
            if data == "":
                response = requests.post(openurl, headers=headers, timeout=30, verify=False).content
            else:
                response = requests.post(openurl, headers=headers, data=data,timeout=30,verify=False).content
        except Exception as e:
            response = {
                'code': 33,
                'message': e,
            }
            response = str(response).encode("utf-8")
            print(f"测试接口发送失败/超时时间:{datetime.datetime.fromtimestamp(time.time())}, 接口url:{url}, 接口入参：{data}")
        return response

    def getStatusCode(self, res):
        try:
            res = res.decode()
            res = res.replace('false', 'False')
            res = res.replace('true', 'True')
            res_dict = eval(res)
            if "ErrCode" in list(res_dict.keys()):
                return res_dict["ErrCode"]
            elif "code" in list(res_dict.keys()):
                return res_dict["code"]
            else:
                return res_dict
        # 记录导出响应无code，响应为文件流，直接decode解码会抛出异常，捕获到该异常认为导出成功
        except UnicodeDecodeError as e:
            return 0
        except Exception as e:
            return 1

    def getResData(self, res):
        try:
            res = res.decode()
            res = res.replace('false', 'False')
            res = res.replace('true', 'True')
            res_dict = eval(res)
            if "Result" in list(res_dict.keys()):
                return res_dict["Result"]
            elif "data" in list(res_dict.keys()):
                return res_dict["data"]
            else:
                return res_dict
        except Exception as e:
            return 1

    def ACC_UAPI_POST(self, url, param):
        openurl = "http://%s:%d%s" % (self.acc_server_ip, self.acc_port, url)
        # 适配post方法无消息体的情况
        if param == "":
            data = param
            content_length = str(0)
        else:
            data = json.JSONEncoder().encode(param)
            content_length = str(len(param))
        response = b""
        headers = {"Content-Type": "application/json",
                   "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36",
                   "Accept": "*/*",
                   "Cache-Control": "no-cache",
                   "Host": "%s:%s" % (self.acc_server_ip, self.acc_port),
                   "Accept-Encoding": "gzip, deflate",
                   "Connection": "keep-alive",
                   "Content-Length": content_length
                   }

        response = self.getResponse(openurl, url, headers, data)
        return response

class HttpMethod(object):
    '''获取token和保活'''
    def __init__(self, server_ip, port, server_user, server_pw):
        self.server_ip = server_ip
        self.port = port
        self.server_user = server_user
        self.server_pw = server_pw
        self.token = self.getAccessToken()
        # 起保活线程
        if self.token != "":
            alive_thread = threading.Thread(target=self.keepAlive)
            alive_thread.setDaemon(True)
            alive_thread.start()

    def getAccessCode(self):
        """
                获取鉴权Token值
                """
        login_url = "/sw/login"
        openurl = "http://%s:%d%s" % (self.server_ip, self.port, login_url)
        AccessCode = ""
        headers = {"Content-Type": "application/json",
                   "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36",
                   "Accept": "*/*",
                   "Cache-Control": "no-cache",
                   "Host": "%s:%s" % (self.server_ip, self.port),
                   "Accept-Encoding": "gzip, deflate",
                   "Connection": "keep-alive",
                   "Content-Length": "0"
                   }
        response = self.getResponse(openurl, login_url, headers, "")
        resData = self.getResData(response)
        if 'AccessCode' in resData:
            AccessCode = resData["AccessCode"]
            print(f"AccessCode获取成功，AccessCode为：{AccessCode}")
        else:
            AccessCode = ''
            ret = resData['ErrCode']
            msg = resData['ErrMsg']
            print(f"AccessCode获取失败，错误码为：{ret},错误信息为：{msg}")
        return AccessCode

    def getloginSignature(self,AccessCode):
        userName_base64 = base64.b64encode(self.server_user.encode('utf-8')).decode('utf-8')
        password_md5 = self.md5(self.server_pw)
        loginSignature1 = userName_base64 + AccessCode + password_md5
        loginSignature = self.md5(loginSignature1)
        return loginSignature

    def getAccessToken(self):
        """
        获取鉴权Token值
        """
        login_url = "/sw/login"
        openurl = "http://%s:%d%s" % (self.server_ip, self.port, login_url)
        AccessCode = self.getAccessCode()
        AccessToken = ""
        param = {"UserName": self.server_user, "AccessCode": AccessCode,"LoginSignature": self.getloginSignature(AccessCode), "isNewVersion": "true", "ip": self.server_ip,
                 "languageType": "zh_cn", "ClientIp": ""}
        param = json.JSONEncoder().encode(param)
        headers = {"Content-Type": "application/json",
                   "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36",
                   "Accept": "*/*",
                   "Cache-Control": "no-cache",
                   "Host": "%s:%s" % (self.server_ip, self.port),
                   "Accept-Encoding": "gzip, deflate",
                   "Connection": "keep-alive",
                   "Content-Length": str(len(param))
                   }
        response = self.getResponse(openurl, login_url, headers, param)
        resData = self.getResData(response)
        if 'AccessToken' in resData:
            AccessToken = resData["AccessToken"]
            print(f"AccessToken获取成功，AccessToken为：{AccessToken}")
        else:
            AccessToken = ''
            ret = resData['ErrCode']
            msg = resData['ErrMsg']
            print(f"AccessToken获取失败，错误码为：{ret},错误信息为：{msg}")
        return AccessToken

    def keepAlive(self):
        timeout = 30
        count = 0
        while True:
            time.sleep(timeout)
            url = "/sw/token/alive/keep"
            res = self.UAPI_GET(url,3)
            ret = self.getStatusCode(res)
            resData = self.getResData(res)
            #如刷新token失败，将减小token刷新间隔
            if ret != 0:
                timeout = 2
                count = count + 1
            else:
                timeout = 30
                count = 0
            #如连续3次token刷新失败，则重新获取token
            if count == 3:
                count = 0
                self.token = self.getAccessToken()


    def md5(self, password):
        password = password.encode('utf-8')
        m = hashlib.md5()
        m.update(password)
        password = m.hexdigest()
        return password

    def getResponse(self, openurl, url, headers, data, timeout=30, method="POST"):
        """
        获取响应体对象
        :param url:
        :param headers:
        :param data:
        :return:
        """
        try:
            if data == "":
                if method == "POST":
                    response = requests.post(openurl, headers=headers, timeout=timeout, verify=False).content
                elif method == "PUT":
                    response = requests.put(openurl, headers=headers, timeout=timeout, verify=False).content
                elif method == "DELETE":
                    response = requests.delete(openurl, headers=headers, timeout=timeout, verify=False).content
                else:
                    response = requests.get(openurl, headers=headers, timeout=timeout, verify=False).content
            else:
                if method == "POST":
                    response = requests.post(openurl, headers=headers, data=data,timeout=timeout,verify=False).content
                elif method == "PUT":
                    response = requests.put(openurl, headers=headers, data=data, timeout=timeout, verify=False).content
                elif method == "DELETE":
                    response = requests.delete(openurl, headers=headers, data=data, timeout=timeout, verify=False).content
                else:
                    response = requests.get(openurl, headers=headers, timeout=timeout, verify=False).content

        except Exception as e:
            if "/sw/login" in openurl:
                print(f"获取token失败/超时时间:{datetime.datetime.fromtimestamp(time.time())}, 接口url:{url}, 接口入参：{data}")
            else:
                print(f"测试接口失败/超时发送时间:{datetime.datetime.fromtimestamp(time.time())}, 接口url:{url}, 接口入参：{data}")
            response = {
                'code': 33,
                'message': e,
            }
            response = str(response).encode("utf-8")
        return response

    def getStatusCode(self, res):
        try:
            res = res.decode()
            res = res.replace('false', 'False')
            res = res.replace('true', 'True')
            res_dict = eval(res)
            if "ErrCode" in list(res_dict.keys()):
                return res_dict["ErrCode"]
            elif "code" in list(res_dict.keys()):
                return res_dict["code"]
            else:
                return res_dict
        # 记录导出响应无code，响应为文件流，直接decode解码会抛出异常，捕获到该异常认为导出成功
        except UnicodeDecodeError as e:
            return 0
        except Exception as e:
            return 1

    def getResData(self, res):
        try:
            res = res.decode()
            res = res.replace('false', 'False')
            res = res.replace('true', 'True')
            res_dict = eval(res)
            if "Result" in list(res_dict.keys()):
                return res_dict["Result"]
            elif "data" in list(res_dict.keys()):
                return res_dict["data"]
            else:
                return res_dict
        except Exception as e:
            return 1

    def UAPI_POST(self, url, param):

        openurl = "http://%s:%d%s" % (self.server_ip, self.port, url)
        #适配post方法无消息体的情况
        if param == "":
            data = param
            content_length = str(0)
        else:
            data = json.JSONEncoder().encode(param)
            content_length = str(len(data))
        response = b""
        headers = {"Authorization": self.token,
                   "Content-Type": "application/json",
                   "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36",
                   "Accept": "*/*",
                   "Cache-Control": "no-cache",
                   "Host": "%s:%s" % (self.server_ip, self.port),
                   "Accept-Encoding": "gzip, deflate",
                   "Connection": "keep-alive",
                   "Content-Length": content_length
                   }
        response = self.getResponse(openurl, url, headers, data)
        return response

    def UAPI_PUT(self, url, param):

        openurl = "http://%s:%d%s" % (self.server_ip, self.port, url)
        #适配post方法无消息体的情况
        if param == "":
            data = param
            content_length = str(0)
        else:
            data = json.JSONEncoder().encode(param)
            content_length = str(len(data))
        response = b""
        headers = {"Authorization": self.token,
                   "Content-Type": "application/json",
                   "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36",
                   "Accept": "*/*",
                   "Cache-Control": "no-cache",
                   "Host": "%s:%s" % (self.server_ip, self.port),
                   "Accept-Encoding": "gzip, deflate",
                   "Connection": "keep-alive",
                   "Content-Length": content_length
                   }
        response = self.getResponse(openurl, url, headers, data, "PUT")
        return response

    def UAPI_DELETE(self, url, param):

        openurl = "http://%s:%d%s" % (self.server_ip, self.port, url)
        #适配post方法无消息体的情况
        if param == "":
            data = param
            content_length = str(0)
        else:
            data = json.JSONEncoder().encode(param)
            content_length = str(len(data))
        response = b""
        headers = {"Authorization": self.token,
                   "Content-Type": "application/json",
                   "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36",
                   "Accept": "*/*",
                   "Cache-Control": "no-cache",
                   "Host": "%s:%s" % (self.server_ip, self.port),
                   "Accept-Encoding": "gzip, deflate",
                   "Connection": "keep-alive",
                   "Content-Length": content_length
                   }
        response = self.getResponse(openurl, url, headers, data, "DELETE")
        return response

    def UAPI_GET(self, url,timeout):

        openurl = "http://%s:%d%s" % (self.server_ip, self.port, url)

        data = ""
        content_length = str(0)
        response = b""
        headers = {"Authorization": self.token,
                   "Content-Type": "application/json",
                   "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36",
                   "Accept": "*/*",
                   "Cache-Control": "no-cache",
                   "Host": "%s:%s" % (self.server_ip, self.port),
                   "Accept-Encoding": "gzip, deflate",
                   "Connection": "keep-alive",
                   "Content-Length": content_length
                   }
        response = self.getResponse(openurl, url, headers, data, timeout, "GET")
        return response






